﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Xml.Serialization;

namespace PathFinder
{
    [Serializable()]
    public class GraphPoint
    {
        #region class definitions

        [XmlIgnore]
        static SolidBrush brush = new SolidBrush(Color.Blue);
        [XmlIgnore]
        static SolidBrush DelBrush = new SolidBrush(Color.Red);
        [XmlIgnore]
        static SolidBrush MovBrush = new SolidBrush(Color.DarkBlue);
        [XmlIgnore]
        static SolidBrush StartMouseOnBrush = new SolidBrush(Color.LightGreen);
        [XmlIgnore]
        static SolidBrush EndMouseOnBrush = new SolidBrush(Color.Pink);
        [XmlIgnore]
        static SolidBrush StartSelectedBrush = new SolidBrush(Color.Green);
        [XmlIgnore]
        static SolidBrush EndSelectedBrush = new SolidBrush(Color.Red);
        [XmlIgnore]
        static SolidBrush BackgroundBrush = new SolidBrush(Color.Black);
        [XmlIgnore]
        static SolidBrush WithNumericBrush = new SolidBrush(Color.LightBlue);
        [XmlIgnore]
        System.Drawing.Font drawFont = new System.Drawing.Font("Arial", 8);
        public Point point;
        public int wayCount;
        [XmlIgnore]
        public bool opened = true;
        [XmlIgnore]
        public double distance = Double.MaxValue;
        private int number = -1;
        public int Number { get { return number; } }

        public GraphPoint() { }

        public GraphPoint(int X, int Y)
        {
            wayCount = 0;
            point = new Point(X, Y);
        }

        public GraphPoint(Point pt)
        {
            point = pt;
        }

        #endregion

        #region drawing functions

        public void Draw(Graphics g)
        {
            if (wayCount == 1)
            {
                g.FillEllipse(brush, point.X - 5, point.Y - 5, 10, 10);
            }
            else
            {
                g.FillEllipse(brush, point.X - 4, point.Y - 4, 8, 8);
            }
        }

        public void DrawDeleting(Graphics g)
        {
            if (wayCount == 1)
            {
                g.FillEllipse(DelBrush, point.X - 5, point.Y - 5, 10, 10);
            }
            else
            {
                g.FillEllipse(DelBrush, point.X - 4, point.Y - 4, 8, 8);
            }
        }

        public void DrawMoving(Graphics g)
        {
            if (wayCount == 1)
            {
                g.FillEllipse(MovBrush, point.X - 5, point.Y - 5, 10, 10);
            }
            else
            {
                g.FillEllipse(MovBrush, point.X - 4, point.Y - 4, 8, 8);
            }
        }

        public void DrawWithNumber(Graphics g, int sign)
        {
            //sign = 0 start, sign = 1 classic, sign = 2 end, sign = 3 start+end
            if (sign == 0)
                g.FillEllipse(StartMouseOnBrush, point.X - 7, point.Y - 7, 14, 14);
            if (sign == 1)
                g.FillEllipse(WithNumericBrush, point.X - 7, point.Y - 7, 14, 14);
            if (sign == 2)
                g.FillEllipse(EndMouseOnBrush, point.X - 7, point.Y - 7, 14, 14);
            if (sign == 3)
            {
                g.FillPie(StartMouseOnBrush, point.X - 7, point.Y - 7, 14, 14, 90, 180);
                g.FillPie(EndMouseOnBrush, point.X - 7, point.Y - 7, 14, 14, 270, 180);
            }
            if (number < 10)
            {
                g.DrawString(number.ToString(), drawFont, BackgroundBrush, point.X - 4, point.Y - 6);
            }
            else
            {
                g.DrawString(number.ToString(), drawFont, BackgroundBrush, point.X - 7, point.Y - 6);
            }
        }

        public void DrawStartMouseOn(Graphics tempGraphics)
        {
            tempGraphics.FillEllipse(StartMouseOnBrush, point.X - 6, point.Y - 6, 12, 12);
        }

        public void DrawEndMouseOn(Graphics tempGraphics)
        {
            tempGraphics.FillEllipse(EndMouseOnBrush, point.X - 6, point.Y - 6, 12, 12);
        }

        public void DrawStartEndMouseOn(Graphics tempGraphics)
        {
            tempGraphics.FillPie(StartMouseOnBrush, point.X - 6, point.Y - 6, 12, 12, 90, 180);
            tempGraphics.FillPie(EndMouseOnBrush, point.X - 6, point.Y - 6, 12, 12, 270, 180);
        }

        public void DrawStartSelected(Graphics tempGraphics)
        {
            tempGraphics.FillEllipse(BackgroundBrush, point.X - 7, point.Y - 7, 14, 14);
            tempGraphics.FillEllipse(StartSelectedBrush, point.X - 6, point.Y - 6, 12, 12);
        }

        public void DrawEndSelected(Graphics tempGraphics)
        {
            tempGraphics.FillEllipse(BackgroundBrush, point.X - 7, point.Y - 7, 14, 14);
            tempGraphics.FillEllipse(EndSelectedBrush, point.X - 6, point.Y - 6, 12, 12);
        }

        public void DrawStartEndSelected(Graphics tempGraphics)
        {
            tempGraphics.FillEllipse(BackgroundBrush, point.X - 7, point.Y - 7, 14, 14);
            tempGraphics.FillPie(StartSelectedBrush, point.X - 6, point.Y - 6, 12, 12, 90, 180);
            tempGraphics.FillPie(EndSelectedBrush, point.X - 6, point.Y - 6, 12, 12, 270, 180);
        }

        public void DrawBackground(Graphics g)
        {
            if (wayCount == 1)
            {
                    g.FillEllipse(BackgroundBrush, point.X - 6, point.Y - 6, 12, 12);
            }
            else
            {
                    g.FillEllipse(BackgroundBrush, point.X - 5, point.Y - 5, 10, 10);
            }
        }

        public void DrawExportBackground(Graphics g)
        {
            g.FillEllipse(BackgroundBrush, point.X - 8, point.Y - 8, 16, 16);
        }

        #endregion

        public bool CompareTo(GraphPoint b)
        {
            if (b == null) return false;
            return (point.X == b.point.X && point.Y == b.point.Y);
        }

        public bool IsNear(Point pt)
        {
            if (GetDistance(pt) <= 12)
                return true;
            return false;
        }

        public double GetDistance(Point pt)
        {
            return (int)Math.Sqrt((point.X - pt.X) * (point.X - pt.X) + (point.Y - pt.Y) * (point.Y - pt.Y));
        }

        public bool Enumerate(int num)
        {
            if (number == -1 || num == -1)
            {
                number = num;
                return true;
            }
            return false;
        }


        public void Validate(Size WindowSize)
        {
            if (point.X < 7 || point.Y < 7 || point.X > WindowSize.Width - 8 || point.Y > WindowSize.Height - 8)
                throw new FormatException();
        }
    }
}
